package com.bdqn.dao;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * BaseDao 数据访问层通用类
 *
 * @author LILIBO
 * @since 2024/4/27
 */
public class BaseDao {

    private static final Logger log = LogManager.getLogger(BaseDao.class);

    private static final String config = "database.properties";

    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    /*
     * 静态代码块，类创建时执行
     */
    static {
        // 加载配置文件
        loadConfig();
        // 加载数据库驱动
        loadDriver();
    }

    /**
     * 加载配置文件
     */
    private static void loadConfig() {
        Properties properties = new Properties();
        try {
            properties.load(BaseDao.class.getClassLoader().getResourceAsStream(config));
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
        } catch (IOException e) {
            log.error(e.fillInStackTrace());
        }
    }

    /**
     * 加载数据库驱动
     */
    private static void loadDriver() {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            log.error(e.fillInStackTrace());
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接对象
     */
    public Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            log.error(e.fillInStackTrace());
        }
        return conn;
    }

    /**
     * 关闭连接释放资源
     *
     * @param rs 数据库结果集对象
     * @param stmt 数据库操作对象
     * @param conn 数据库连接对象
     */
    public void closeAll(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                log.error(e.fillInStackTrace());
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                log.error(e.fillInStackTrace());
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                log.error(e.fillInStackTrace());
            }
        }
    }

    /**
     * 执行通用增删改
     *
     * @param sql 需要执行的SQL语句
     * @param params SQL语句问号处对应的参数
     * @return 执行该语句影响的行数
     */
    public int execute(String sql, Object[] params) {
        // 返回受影响的行数
        int row = 0;

        // 获取数据库连接
        Connection conn = this.getConnection();
        PreparedStatement pstmt = null;
        try {
            // 创建数据库操作对象预处理SQL语句
            pstmt = conn.prepareStatement(sql);
            // 给SQL语句问号处设置参数
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
            // 执行增删改操作返回受影响行数
            row = pstmt.executeUpdate();
        } catch (SQLException e) {
            log.error(e.fillInStackTrace());
        } finally {
            // 关闭连接释放资源
            this.closeAll(null, pstmt, conn);
        }
        return row;
    }

}
